package com.hospital.payment.module.message;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hospital.common.dto.diagnosis.module.ChatStatusDTO;
import com.hospital.common.enums.diagnosis.module.SessionStatus;
import com.hospital.common.enums.payment.module.OrderStatus;
import com.hospital.common.enums.payment.module.OrderType;
import com.hospital.common.enums.payment.module.PaymentStatus;
import com.hospital.common.pojo.TOrder;
import com.hospital.common.utils.ThreadLocalUtils;
import com.hospital.payment.module.exception.OrderServiceException;
import com.hospital.payment.module.exception.enums.OrderServiceExpCode;
import com.hospital.payment.module.feign.DiagnosisModuleFeign;
import com.hospital.payment.module.service.TOrderService;
import com.hospital.payment.module.service.TRegistrationService;
import com.hospital.payment.module.utils.MinioUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

/**
 * 订单超时消费者
 */
@Component
@RocketMQMessageListener(
        topic = "${topic.order-timeout}",
        consumerGroup = "${rocketmq.consumer.group}",
        messageModel = MessageModel.CLUSTERING
)
public class OrderTimeoutConsumer implements RocketMQListener<OrderTimeoutMessage> {
    @Autowired
    private TOrderService orderService;
    @Autowired
    private TRegistrationService registrationService;
    @Autowired
    private MinioUtils minioUtils;
    @Autowired
    private DiagnosisModuleFeign diagnosisModuleFeign;
    @Override
    @GlobalTransactional
    public void onMessage(OrderTimeoutMessage orderTimeoutMessage) {
        LambdaQueryWrapper<TOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TOrder::getOrderId, orderTimeoutMessage.getOrderId())
                .select(TOrder::getQrcodeUrl);
        TOrder order = orderService.getOne(queryWrapper);
        if(ObjectUtils.isEmpty(order)){
            throw new OrderServiceException(OrderServiceExpCode.ORDER_NOT_EXIST);
        }
        OrderType orderType = OrderType.valueOf(orderTimeoutMessage.getOrderType());
        if(ObjectUtils.isEmpty(orderType)){
            throw new OrderServiceException(OrderServiceExpCode.ORDER_TYPE_NOT_EXIST);
        }
        if(!ObjectUtils.isEmpty(orderTimeoutMessage.getThreadAttributes())){
            ThreadLocalUtils.set(orderTimeoutMessage.getThreadAttributes());
        }
        switch (orderType){
            case REGISTRATION -> {
                registrationService.cancelRegistration(order.getBusinessId());
            }
            case ONLINE_DIAGNOSIS -> {
                diagnosisModuleFeign.updateChatStatus(ChatStatusDTO.builder().status(SessionStatus.PAY_FAILED.value).sessionId(order.getSessionId()).build());
            }
        }
        LambdaUpdateWrapper<TOrder> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(TOrder::getOrderId, orderTimeoutMessage.getOrderId())
                .set(TOrder::getPaymentStat, PaymentStatus.FAILED.value)
                .set(TOrder::getOrderStatus, OrderStatus.CANCELED.value);
        if(!orderService.update(updateWrapper)){
            throw new OrderServiceException(OrderServiceExpCode.ORDER_STATUS_UPDATE_FAILED);
        }
        minioUtils.deleteFile(order.getQrcodeUrl());
    }
}
